package org.study.lambda;

import com.alibaba.fastjson2.JSON;

import java.time.LocalDate;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 类的描述
 *
 * @author Administrator
 * @date 2021-08-31
 */
public class LambdaGroupTests {
    public static void main(String[] args) {
        testLambda2Map();

        testLambdaGroupingBy();
    }

    private static List<Student> studentList = new ArrayList<>();

    static {
        Student student1 = new Student(1, "M", "张三", LocalDate.of(1990, 5, 21));
        Student student2 = new Student(2, "F", "李四", LocalDate.of(1994, 10, 20));
        Student student3 = new Student(3, "F", "王五", LocalDate.of(1996, 8, 29));
        Student student4 = new Student(5, "M", "赵六", LocalDate.of(2008, 8, 8));
        studentList.add(student1);
        studentList.add(student2);
        studentList.add(student3);
        studentList.add(student4);
    }

    public static void testLambda2Map() {
        System.out.println("========== 华丽的分割线 ==========");
        // 一个属性作为key，一个属性作为 value
        Map<Integer, String> integerStringMap = studentList.stream().collect(Collectors.toMap(Student::getId, Student::getName));
        System.out.println(JSON.toJSONString(integerStringMap));

        // 收集成实体本身Map：student -> student 是一个返回本身的 lambda 表达式，可以使用 Function 接口中的 identity() 方法代替，使整个方法更简洁优雅
        Map<Integer, Student> integerStudentMap1 = studentList.stream().collect(Collectors.toMap(Student::getId, student -> student));
        System.out.println(JSON.toJSONString(integerStudentMap1));
        Map<Integer, Student> integerStudentMap2 = studentList.stream().collect(Collectors.toMap(Student::getId, Function.identity()));
        System.out.println(JSON.toJSONString(integerStudentMap2));

        // 重复 key 的情况：报错 java.lang.IllegalStateException: Duplicate key，因为 sex 重复了。toMap() 有个重载方法，可以传入一个合并函数来解决 key 冲突问题
        //Map<String, Student> stringStudentMap1 = studentList.stream().collect(Collectors.toMap(Student::getSex, Function.identity()));
        //System.out.println(JSON.toJSONString(stringStudentMap1));
        // 使用后者覆盖前者解决 key 重复问题
        Map<String, Student> stringStudentMap2 = studentList.stream().collect(Collectors.toMap(Student::getSex, Function.identity(), (key1, key2) -> key2));
        System.out.println(JSON.toJSONString(stringStudentMap2));

        //指定具体收集的 Map：toMap() 还有另一个重载方法，可以指定一个 Map 的具体实现来收集数据
        LinkedHashMap<Integer, Student> studentLinkedHashMap = studentList.stream().collect(Collectors.toMap(Student::getId, Function.identity(), (key1, key2) -> key2, LinkedHashMap::new));
        System.out.println(JSON.toJSONString(studentLinkedHashMap));
    }

    public static void testLambdaGroupingBy() {
        System.out.println("========== 华丽的分割线 ==========");
        // 单一分组条件,根据code
        Map<String, List<Student>> singleMap = studentList.stream().collect(Collectors.groupingBy(Student::getSex));
        System.out.println(JSON.toJSONString(singleMap));

        // 组合分组条件
        Map<String, List<Student>> complexMap = studentList.stream().collect(Collectors.groupingBy(e -> e.getSex() + "+" + e.getId()));
        System.out.println(JSON.toJSONString(complexMap));

        List<Student> studentList1 = complexMap.get("M+1");
        System.out.println(JSON.toJSONString(studentList1));

        List<Student> studentList2 = complexMap.get("F+2");
        System.out.println(JSON.toJSONString(studentList2));
    }
}
